package com.trackerapp.screen;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONObject;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import com.trackerapp.CommonUtilities;
import com.trackerapp.R;
import com.trackerapp.database.CellIDCacheManager;
import com.trackerapp.model.PushMessage;
import com.trackerapp.network.HttpConnection;
import com.trackerapp.service.LocationService;
import com.trackerapp.util.MessageUtil;
import com.trackerapp.util.TrackerPreferenceManager;

public class TrackDeliveryActivity extends Activity {

	Button start;
	Button stop;
	EditText billEdit;
	Intent serviceIntent; 
	ListView mPushMessagesList;
	List<PushMessage> mListData;
	EfficientAdapter mAdapter;
	ProgressDialog mProgress;
	Spinner spinner;
	String delivery_content;
	String bill_number;
	ArrayAdapter<CharSequence> adapter;
	boolean delivery_started;
	String device_id;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.landing_screen_layout);
		mProgress = new ProgressDialog(this);
		mProgress.setCancelable(false);
		
		delivery_content = "";
		bill_number="";
		device_id = TrackerPreferenceManager.getString(TrackerPreferenceManager.PreferenceKeys.DEVICE_ID, "");
		
		start = (Button) findViewById(R.id.start_tracker);
		stop = (Button) findViewById(R.id.stop_tracker);

		billEdit = (EditText) findViewById(R.id.bill_number);
		
		spinner = (Spinner) findViewById(R.id.delivery_spinner);
		
		adapter = ArrayAdapter.createFromResource(this,
		        R.array.delivery_content, android.R.layout.simple_spinner_item);
    
		spinner.setAdapter(adapter);

		spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
		    @Override
		    public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
		    	delivery_content = adapter.getItem(position).toString();
		    }

		    @Override
		    public void onNothingSelected(AdapterView<?> parentView) {
		        // your code here
		    }

		});
		
		
		delivery_started = TrackerPreferenceManager.getBoolean(TrackerPreferenceManager.PreferenceKeys.DELIVERY_STARTED, false);
		if(delivery_started) {			
			delivery_content = TrackerPreferenceManager.getString(TrackerPreferenceManager.PreferenceKeys.DELIVERY_CONTENT, "");
			bill_number = TrackerPreferenceManager.getString(TrackerPreferenceManager.PreferenceKeys.BILL_NUMBER, "");
			billEdit.setText(bill_number);	
			start.setEnabled(false);
		} else {
			stop.setEnabled(false);
		}

		
		serviceIntent = new Intent(TrackDeliveryActivity.this, LocationService.class);
		start.setOnClickListener( new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				//
				System.out.println(" ####### Start clicked ######## ");
				// POST the start delivery details to server.
				postStartDelivery();
			}
		});
		
		stop.setOnClickListener( new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				System.out.println(" ####### Stop clicked ######## ");
				//
				postStopDelivery();
			}
		});
		mPushMessagesList = (ListView) findViewById(R.id.push_messages_list);
		mListData = new ArrayList<PushMessage>();
		mAdapter = new EfficientAdapter(this);
		mPushMessagesList.setAdapter(mAdapter);
		
		registerReceiver(mHandleMessageReceiver, new IntentFilter(CommonUtilities.RECEIVED_PUSH_MESSAGE));
		loadPushMessagesTask();
	}

	public void onDestroy() {
		super.onDestroy();
		if( mHandleMessageReceiver != null) {
			unregisterReceiver(mHandleMessageReceiver);
			mHandleMessageReceiver = null;
		}
	}

	private BroadcastReceiver mHandleMessageReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
        	
        	System.out.println(" ON RECEIVE *************** "+intent.getAction());
        	
        	if (intent.getAction().equals(CommonUtilities.RECEIVED_PUSH_MESSAGE)) {
        		String pushMessage = intent.getExtras().getString(CommonUtilities.PUSH_MESSAGE);
        		String pushMessageId = intent.getExtras().getString(CommonUtilities.PUSH_MESSAGE_ID);
        		PushMessage push = new PushMessage(pushMessage,pushMessageId,"server");
        		
        		// Add to the db.
        		if(  CellIDCacheManager.getInstance().addPushMessage(push) > 0 ) {
        			// Success inform the listview to update its content.
        			loadPushMessagesTask();
        		}
        	} 

        }
    };
    
    Handler mHandler = new Handler();
    private void loadPushMessagesTask() {
		AsyncTask<Void, Void, Void> getIdsTask = new AsyncTask<Void, Void, Void>(){

			@Override
			protected Void doInBackground(Void...params) {
				// TODO:: User sync to avoid listview using mListdata while fetching.
				mListData = CellIDCacheManager.getInstance().getAllPushMessages();
				mHandler.post( new Runnable() {
					public void run() {
						updateUI();	
					}
				});
				
				return null;
			}
		};
		
		getIdsTask.execute();

    }
    
    private void updateUI() {
    	mAdapter.notifyDataSetChanged();
    }
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.landing_screen_layout, menu);
		return true;
	}

	   private  class EfficientAdapter extends BaseAdapter {
	        private LayoutInflater mInflater;
	        SimpleDateFormat sdf;
	        public EfficientAdapter(Context context) {
	            // Cache the LayoutInflate to avoid asking for a new one each time.
	            mInflater = LayoutInflater.from(context);
	            sdf = new SimpleDateFormat("dd-MMM-yyyy hh:mm a");
	        }

	        public int getCount() {
	            return mListData.size();
	        }
	        
	        public Object getItem(int position) {
	            return position;
	        }

	        public long getItemId(int position) {
	            return position;
	        }

	        public View getView(int position, View convertView, ViewGroup parent) {
	            ViewHolder holder;
	            final int pos = position;

	            if (convertView == null) {
	                convertView = mInflater.inflate(R.layout.push_message_list_item, null);
	                holder = new ViewHolder();
	                holder.push_message = (TextView) convertView.findViewById(R.id.push_message);
	                holder.time = (TextView) convertView.findViewById(R.id.time);
	                holder.respond = (Button) convertView.findViewById(R.id.respond);
	                holder.server_sent = (ImageView) convertView.findViewById(R.id.server_image);
	                holder.user_sent = (ImageView) convertView.findViewById(R.id.user_image);
	                convertView.setTag(holder);
	            } else {
	                holder = (ViewHolder) convertView.getTag();
	            }
	            
	            
	            holder.push_message.setText(mListData.get(position).getPush_message());
	            System.out.println(" ##### TIme for message ##### "+mListData.get(position).getCreatedAt());
	            if(mListData.get(position).getCreatedAt() > 0)
	            	holder.time.setText(sdf.format(new Date(mListData.get(position).getCreatedAt() * 1000)));
	            
	            if(mListData.get(position).getSender().equals("server")) {
	            	holder.user_sent.setVisibility(View.GONE);
	            } else {
	            	holder.server_sent.setVisibility(View.GONE);
	            	holder.respond.setVisibility(View.GONE);
	            }
	            
	            holder.respond.setOnClickListener( new View.OnClickListener() {
					@Override
					public void onClick(View v) {
						v.performHapticFeedback (android.view.HapticFeedbackConstants.VIRTUAL_KEY, android.view.HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
						long id = mListData.get(pos).getId();
						sendReply(mListData.get(pos).getPush_messag_id());
						System.out.println("###### On click respond ####### "+id);
					}
				});
	            
	            
	            return convertView;
	        }
	         class ViewHolder {
	            TextView push_message;
	            TextView time;
	            Button respond;
	            ImageView server_sent;
	            ImageView user_sent;
	        }
	    }
	   
	   private void sendReply(final String push_message_id) {
		   System.out.println(" ##### send reply push message id ######## "+push_message_id);
		   // Show alert dialog to get the reply message.
		   final AlertDialog.Builder alert = new AlertDialog.Builder(this);
		   LayoutInflater mInflater = LayoutInflater.from(this);
		   View alertView = mInflater.inflate(R.layout.send_reply_layout, null);
		   final EditText reply = (EditText)alertView.findViewById(R.id.send_reply_edit);
		   alert.setTitle("Send Reply");
		   alert.setView(alertView);
		   alert.setPositiveButton("Send", new DialogInterface.OnClickListener() {
		        public void onClick(DialogInterface dialog, int whichButton) {
		            String value = reply.getText().toString().trim();
		            postReply(value,push_message_id);
		            Toast.makeText(getApplicationContext(), value, Toast.LENGTH_SHORT).show();
		        }
		    });

		   alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
		        public void onClick(DialogInterface dialog, int whichButton) {
		            dialog.cancel();
		        }
		   });
		   alert.show();       
	   }
	   
	   private void postReply(String push_message, String push_message_id) {
		   
		   System.out.println(" ##### postReply ######## "+push_message+" ::  "+push_message_id);
		   showProgressDialog("Sending reply");
	       HttpConnection connection = new HttpConnection(registerHandler);

	        String url = "http://ec2-54-242-153-20.compute-1.amazonaws.com:3000/respond_push_message";

	        connection.addHeader("Accept", "application/xml");
//	        connection.addCookie("_session_id", session);

	        connection.addParam("respond_message", push_message);
	        connection.addParam("device_id", TrackerPreferenceManager.getString(TrackerPreferenceManager.PreferenceKeys.DEVICE_ID, "0"));
	        connection.addParam("push_message_id", push_message_id);
	        connection.post(url);
	   }
	   
	    final Handler registerHandler = new Handler() {
	        @Override
	        public void handleMessage(Message msg) {
	            super.handleMessage(msg);
	            switch (msg.what) {
	                case HttpConnection.REQUEST_START:
	                	System.out.println(" #### START ######## ");
	                    break;
	                case HttpConnection.REQUEST_SUCCEED:
	                	String result = (String) msg.obj;
	                	System.out.println(" #### SUCESS ######## "+result);
	                	try {
	                		JSONArray data = new JSONArray(result);
	                		
	                		// Check for http status code.
	                		JSONObject httpStatusJson = data.getJSONObject(0);
	                		String httpStatus = httpStatusJson.getString("status");
	                		if( httpStatus.equals("200")) {                			
	                			// Get user_id, device_id, session_id.
	                			String push_message_id = data.getJSONObject(1).getString("push_message_id");
	                			String respond_message = data.getJSONObject(1).getString("respond_message");
	                			// Add to the db.
	                    		PushMessage push = new PushMessage(respond_message,push_message_id,"user");	                    		
	                    		// Add to the db.
	                    		if(  CellIDCacheManager.getInstance().addPushMessage(push) > 0 ) {
	                    			// Success inform the listview to update its content.
	                    			loadPushMessagesTask();
	                    		}

	                			
	                		} else if(httpStatus.equals("422") || httpStatus.equals("404") || httpStatus.equals("401")) {
	                			showErrorDialog("ERROR",data.getJSONObject(1).getString("errorcode"), data.getJSONObject(1).getString("error")+data.getJSONObject(1).getString("extra_info"));
	                		} else {
	                			
	                		}
	                	} catch(Exception e) {
	                		e.printStackTrace();
	                	}                	
	                	
	                    break;
	                case HttpConnection.REQUEST_ERROR:                    
	                    MessageUtil.showMessage((String) msg.obj, false);
	                    break;
	                case HttpConnection.INVALID_SESSION:
	                	System.out.println(" #### INVALID SESSION ######## ");
	                    break;
	            }
	        }

	    };
		
	    private void showErrorDialog(String title,String errorCode, String errorMessage) {
	    	
	    	new AlertDialog.Builder(this)
	        .setTitle(title)
	        .setMessage(errorCode+" : "+errorMessage)
	        .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
	            public void onClick(DialogInterface dialog, int which) { 
	                // continue with delete
	            }
	         }).show();
	    }
	    
	    private void showProgressDialog(String msg) {
	    	mProgress.setMessage(msg);
	    	mProgress.show();
	    }
	    
	    final Handler startDeliveryHandler = new Handler() {
	        @Override
	        public void handleMessage(Message msg) {
	            super.handleMessage(msg);
	            switch (msg.what) {
	                case HttpConnection.REQUEST_START:
	                	System.out.println(" #### START ######## ");
	                    break;
	                case HttpConnection.REQUEST_SUCCEED:
	                	mProgress.dismiss();
	                	String result = (String) msg.obj;
	                	System.out.println(" #### SUCESS ######## "+result);
	                	try {
	                		JSONArray data = new JSONArray(result);
	                		
	                		// Check for http status code.
	                		JSONObject httpStatusJson = data.getJSONObject(0);
	                		String httpStatus = httpStatusJson.getString("status");
	                		if( httpStatus.equals("200")) {                			
	                			// Get user_id, device_id, session_id.
	                			String delivery_Id = data.getJSONObject(1).getString("id");
	                			System.out.println(" ####### Delivery ID ######## "+delivery_Id);
	                			MessageUtil.showMessage("Successfully started tracking", false);
	            				// Update the preference.
	            				TrackerPreferenceManager.setBoolean(TrackerPreferenceManager.PreferenceKeys.DELIVERY_STARTED,true);
	            				TrackerPreferenceManager.setString(TrackerPreferenceManager.PreferenceKeys.DELIVERY_ID,delivery_Id);
	            				TrackerPreferenceManager.setString(TrackerPreferenceManager.PreferenceKeys.DELIVERY_CONTENT,delivery_content);
	            				TrackerPreferenceManager.setString(TrackerPreferenceManager.PreferenceKeys.BILL_NUMBER,billEdit.getText().toString());
	            				start.setEnabled(false);
	            				stop.setEnabled(true);
	            				//TrackDeliveryActivity.this.startService(serviceIntent);
	            				
	                		} else if(httpStatus.equals("422") || httpStatus.equals("404") || httpStatus.equals("401")) {
	                			showErrorDialog("ERROR",data.getJSONObject(1).getString("errorcode"), data.getJSONObject(1).getString("error")+data.getJSONObject(1).getString("extra_info"));
	                		} else {
	                			
	                		}
	                	} catch(Exception e) {
	                		e.printStackTrace();
	                		MessageUtil.showMessage("ERROR: Invaid URL", false);
	                	}                	
	                	
	                    break;
	                case HttpConnection.REQUEST_ERROR:  
	                	mProgress.dismiss();
	                    MessageUtil.showMessage((String) msg.obj, false);
	                    break;
	                case HttpConnection.INVALID_SESSION:
	                	mProgress.dismiss();
	                	System.out.println(" #### INVALID SESSION ######## ");
	                	MessageUtil.showMessage("INVALID SESSION", false);
	                    break;
	            }
	        }

	    };
	    private void postStartDelivery() {
		   System.out.println(" ##### postStartDelivery ######## "+bill_number);
	      
		   String billNumber = billEdit.getText().toString();
		   
		   if( billNumber.length() == 0) {
	    	   MessageUtil.showMessage("Bill Number cannot be empty", false);
	    	   return;
	       }

	       
		   showProgressDialog("Starting tracking...");
	       HttpConnection connection = new HttpConnection(startDeliveryHandler);

	       String url = "http://ec2-54-242-153-20.compute-1.amazonaws.com:3000/device/"+device_id+"/delivery";

	        connection.addHeader("Accept", "application/xml");
//		    connection.addCookie("_session_id", session);

	        connection.addParam("delivery_content", delivery_content);
	        connection.addParam("bill_number", billNumber);
	        connection.post(url);	    	
	    }
	    
	    final Handler stopDeliveryHandler = new Handler() {
	        @Override
	        public void handleMessage(Message msg) {
	            super.handleMessage(msg);
	            switch (msg.what) {
	                case HttpConnection.REQUEST_START:
	                	System.out.println(" #### START ######## ");
	                    break;
	                case HttpConnection.REQUEST_SUCCEED:
	                	mProgress.dismiss();
	                	String result = (String) msg.obj;
	                	System.out.println(" #### SUCESS ######## "+result);
	                	try {
	                		JSONArray data = new JSONArray(result);
	                		
	                		// Check for http status code.
	                		JSONObject httpStatusJson = data.getJSONObject(0);
	                		String httpStatus = httpStatusJson.getString("status");
	                		if( httpStatus.equals("200")) {
	                			MessageUtil.showMessage("Successfully stopped tracking", false);
	            				TrackerPreferenceManager.setBoolean(TrackerPreferenceManager.PreferenceKeys.DELIVERY_STARTED,false);
	            				TrackerPreferenceManager.setString(TrackerPreferenceManager.PreferenceKeys.DELIVERY_CONTENT,"");
	            				TrackerPreferenceManager.setString(TrackerPreferenceManager.PreferenceKeys.BILL_NUMBER,"");
	            				start.setEnabled(true);
	            				stop.setEnabled(false);
	            				billEdit.setText("");
	            				spinner.setSelection(2);				
	            				
	            				//TrackDeliveryActivity.this.stopService(serviceIntent);
	                		} else if(httpStatus.equals("422") || httpStatus.equals("404") || httpStatus.equals("401")) {
	                			showErrorDialog("ERROR",data.getJSONObject(1).getString("errorcode"), data.getJSONObject(1).getString("error")+data.getJSONObject(1).getString("extra_info"));
	                		} else {
	                			
	                		}
	                	} catch(Exception e) {
	                		e.printStackTrace();
	                	}                	
	                	
	                    break;
	                case HttpConnection.REQUEST_ERROR:  
	                	mProgress.dismiss();
	                    MessageUtil.showMessage((String) msg.obj, false);
	                    break;
	                case HttpConnection.INVALID_SESSION:
	                	mProgress.dismiss();
	                	System.out.println(" #### INVALID SESSION ######## ");
	                    break;
	            }
	        }

	    };
	    
	    
	    private void postStopDelivery() {
		   System.out.println(" ##### postReply ######## ");
		   
	       HttpConnection connection = new HttpConnection(stopDeliveryHandler);
	       String delivery_id = TrackerPreferenceManager.getString(TrackerPreferenceManager.PreferenceKeys.DELIVERY_ID, "0");
	       int id = Integer.parseInt(delivery_id);
	       if( id == 0) {
	    	   MessageUtil.showMessage("INVALID Delivery ID", false);
	    	   return;
	       }
	        showProgressDialog("Stopping Tracking....");
	        String url = "http://ec2-54-242-153-20.compute-1.amazonaws.com:3000/device/"+device_id+"/delivery/"+delivery_id;

	        connection.addHeader("Accept", "application/xml");
//		        connection.addCookie("_session_id", session);
	        connection.addParam("delivered", "1");
	        
	       connection.put(url);	    	
	    }
}
